package Controllers

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
	
	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"
	
	"hyper/supports/cryption"
	"hyper/supports/path"
	"hyper/supports/response"
)

// 基础控制器
type BaseController struct{}

// 公钥加密
func (b *BaseController) Encode(c *gin.Context) {
	
	data := c.PostForm("data")
	
	// 拼接公钥地址
	pubPath := fmt.Sprintf("%s/public_key.pem", path.Secret)
	
	// 读取文件
	pubF, err := os.Open(pubPath)
	if err != nil {
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	// 获取文件详细信息
	info, err := pubF.Stat()
	if err != nil {
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	// 公钥
	pubKey := make([]byte, info.Size())
	pubF.Read(pubKey)
	
	// 加密
	newData, err := cryption.RsaEncrypt(data, string(pubKey))
	if err != nil {
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	response.ResponseException(c, http.StatusOK, "Success", newData)
	return
}

// 私钥解密
func (b *BaseController) Decode(c *gin.Context) {
	data := c.PostForm("data")
	
	// 拼接私钥地址
	private := fmt.Sprintf("%s/private_key.pem", path.Secret)
	
	// 读取文件
	prvF, err := os.Open(private)
	if err != nil {
		fmt.Println(err.Error())
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	// 获取文件详细信息
	info, err := prvF.Stat()
	if err != nil {
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	// 私钥
	privateKey := make([]byte, info.Size())
	prvF.Read(privateKey)
	
	newData, err := cryption.RsaDecrypt(data, string(privateKey))
	if err != nil {
		response.ResponseException(c, http.StatusOK, err.Error(), nil)
		return
	}
	
	response.ResponseException(c, http.StatusOK, "Success", newData)
	return
}

// 文件上传
func (b *BaseController) Upload(c *gin.Context) {
	scheme := "http"
	if c.Request.TLS != nil {
		scheme = "https"
	}
	host := c.Request.Host
	
	file, err := c.FormFile("file")
	
	if err != nil {
		response.ResponseException(c, http.StatusContinue, err.Error(), nil)
		return
	}
	
	// 打开上传的文件
	uploadedFile, err := file.Open()
	if err != nil {
		response.ResponseException(c, http.StatusContinue, err.Error(), nil)
		return
	}
	defer uploadedFile.Close()
	
	// 读取文件内容到内存
	_, e := io.ReadAll(uploadedFile)
	if e != nil {
		response.ResponseException(c, http.StatusContinue, e.Error(), nil)
		return
	}
	
	now := time.Now().Format(time.DateOnly)
	
	staticPath := fmt.Sprintf("%s/uploads/%s", path.PucPath, now)
	
	// 判断目录是否存在
	if _, err := os.Stat(staticPath); os.IsNotExist(err) {
		// 目录不存在，创建目录
		err = os.MkdirAll(staticPath, os.ModePerm)
		if err != nil {
			response.ResponseException(c, http.StatusContinue, err.Error(), nil)
			return
		}
	}
	
	newFileName := fmt.Sprintf("%s%s", uuid.NewV4(), filepath.Ext(file.Filename))
	dst := fmt.Sprintf("%s/%s", staticPath, newFileName)
	
	// 保存文件到指定的路径
	err = c.SaveUploadedFile(file, dst)
	if err != nil {
		response.ResponseException(c, http.StatusContinue, err.Error(), nil)
		return
	}
	
	realPath := fmt.Sprintf("%s/%s", staticPath, newFileName)
	
	domain := fmt.Sprintf("%s://%s%s", scheme, host, strings.ReplaceAll(realPath, path.PucPath, ""))
	
	response.ResponseException(c, http.StatusOK, "Success", response.D{
		"message":  "ok",
		"realPath": realPath,
		"path":     domain,
	})
}
